package values

import (
	"fmt"
	"soluty.cc/go/xlog"
	"soluty.cc/go/xmath"
)

type modifierList struct {
	totalValue int32
	modifiers  []*Modifier
	holder     interface{}
	formula    Formula
}

func (l *modifierList) Len() int {
	return len(l.modifiers)
}

func (l *modifierList) String() string {
	return fmt.Sprintf("%v|%v", l.totalValue, l.modifiers)
}

func (l *modifierList) SetFormula(formula Formula) {
	l.formula = formula
}

func (l *modifierList) AddModifier(m *Modifier) {
	l.modifiers = append(l.modifiers, m)
}

func (l *modifierList) RemoveModifier(m *Modifier) {
	for i, value := range l.modifiers {
		if value == m {
			l.modifiers = append(l.modifiers[:i], l.modifiers[i+1:]...)
			break
		}
	}
}

func (l *modifierList) update() (err error) {
	l.totalValue = 0
	for _, m := range l.modifiers {
		var val int32
		if m.ValueFunc != nil {
			val, err = m.ValueFunc(l.holder, m.Params, l.formula)
			if err != nil {
				err = xlog.Errorf(xlog.Fmt(), fmt.Sprintf("%v", l), err)
				l.totalValue = 0
				return
			}
		} else {
			if m.Cond == nil || m.Cond(l.holder, m.Params, l.formula) {
				val = m.Value
			}
		}
		if val == 0 {
			continue
		}
		v, err := xmath.Add(l.totalValue, val)
		if err != nil {
			l.totalValue = 0
			return xlog.Errorf(xlog.Fmt(), fmt.Sprintf("%v", l), err)
		}
		l.totalValue = v
	}
	return nil
}
